package com.liqi.web.controller.openapi.middleware;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.liqi.common.core.controller.BaseController;
import com.liqi.common.core.domain.R;
import com.liqi.common.utils.StringUtils;
import com.liqi.deployment.domain.DvDeployment;
import com.liqi.deployment.domain.DvDeploymentModule;
import com.liqi.deployment.domain.dto.DeploymentModuleDto;
import com.liqi.deployment.service.IDvDeploymentModuleService;
import com.liqi.deployment.service.IDvDeploymentService;
import com.liqi.monitor.domain.DvDeploymentDiskInfo;
import com.liqi.monitor.domain.DvDeploymentPatrol;
import com.liqi.monitor.domain.DvDeploymentSystem;
import com.liqi.monitor.domain.DvFaultLog;
import com.liqi.monitor.domain.dto.CpuDto;
import com.liqi.monitor.domain.dto.DiskDto;
import com.liqi.monitor.domain.dto.DiskPartitions;
import com.liqi.monitor.domain.dto.DvSystemInfoDto;
import com.liqi.monitor.domain.dto.MemoryDto;
import com.liqi.monitor.domain.dto.NetworkAdapter;
import com.liqi.monitor.domain.dto.PrinterDto;
import com.liqi.monitor.domain.dto.SelfInspectionInfo;
import com.liqi.monitor.service.IDvDeploymentDiskInfoService;
import com.liqi.monitor.service.IDvDeploymentPatrolService;
import com.liqi.monitor.service.IDvDeploymentSystemService;
import com.liqi.monitor.service.IDvFaultLogService;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;

/**
 * 开机自检接口
 *
 */
@Api(tags = "提供给中间件的接口")
@RestController
@RequestMapping("/openApi/middleware")
@EnableAspectJAutoProxy(exposeProxy = true)
public class SelfInspectionController extends BaseController {

	private static final Logger logger = LoggerFactory.getLogger(SelfInspectionController.class);

	@Autowired
	private IDvDeploymentModuleService deploymentModuleService;
	@Autowired
	private IDvDeploymentService deploymentService;
	@Autowired
	private IDvFaultLogService faultLogService;
	@Autowired
	private IDvDeploymentPatrolService patrolService;

	@Autowired
	private IDvDeploymentSystemService systemService;
	
	@Autowired
	private IDvDeploymentDiskInfoService  diskInfoService;

	/**
	 * 开机自检
	 */
	@ApiOperation("设备自检上报")
	@PostMapping(value = "/saveSelfInspectionResult")
	public R saveSelfInspectionResult(@Validated @RequestBody SelfInspectionInfo selfInspectionInfo) {
		String deviceId = selfInspectionInfo.getDeviceId();

		DvDeployment deployment = deploymentService.getByDeviceId(deviceId);

		if (deployment == null) {
			return R.fail("找不到当前设备。deviceId=" + deviceId);
		}

		// 设备模块是否出现异常
		boolean errorStatus = false;
		// 业务逻辑
		List<String> errorMessages = new ArrayList<>();
		
		Date now = new Date();
		
		for (DeploymentModuleDto dm : selfInspectionInfo.getModuleList()) {
			if (StringUtils.isBlank(dm.getModuleCode())) {
				return R.fail("模块编码不能为空。");
			}
			
			DvDeploymentModule module = new DvDeploymentModule();
			
			// 将自编设备号设置进投放模块实体中
			module.setDeviceId(deviceId);
			module.setDeviceCode(deployment.getDeviceCode());
			module.setDeviceName(deployment.getDeviceName());
			module.setModelCode(dm.getModuleCode());
			module.setModelName(dm.getModuleName());
			module.setModelStatus(dm.getModuleStatus());
			module.setAdapterVersion(dm.getAdapterVersion());
			module.setErrorCode(dm.getErrorCode());
			module.setMessage(dm.getMessage());

			// 如果模块状态为异常，插入数据，修改状态，0是正常，1是异常
			if (dm.getModuleStatus() == 1) {
				errorMessages.add("模块名称："+ dm.getModuleName() + "，错误码：" + dm.getErrorCode() + "，错误信息：" + dm.getMessage());
				errorStatus = true;

				// ============第一：如果发现模块异常，调用插入异常逻辑
				// 如果设备出现异常，根据异常deviceId、异常码(由中间件定义)、今天时间、异常类型(0运行中上报 1人工上报
				// 2开机自检上报)作为与条件判定为唯一标记，那么每台设备通过心跳增加的异常信息，通过心跳、自检、运行过程中，发现的异常每天只允许发一条到异常表
				DvFaultLog log = new DvFaultLog();
				log.setDeviceId(deviceId);
				log.setEquipmentFalutType("2");
				// 设备自检异常上报
				log.setErrorCode(dm.getErrorCode());
				log.setErrorMessage(dm.getMessage());

				log.setDeviceCode(deployment.getDeviceCode());
				log.setDeviceName(deployment.getDeviceName());
				log.setModelCode(dm.getModuleCode());
				log.setModelName(dm.getModuleName());
				log.setDeptId(deployment.getDeptId());
				log.setCreateUserId(deployment.getCreateUserId());
				log.setCreateTime(now);
				log.setCreateBy("admin");

				faultLogService.insertNonmanualFaultLog(log);
			}
			// 设备模块未出现在模块表中，自动插入一条数据
			DvDeploymentModule search = new DvDeploymentModule();
			search.setDeviceId(deviceId);
			search.setModelCode(dm.getModuleCode());

			// ============第二：先更新模块状态。
			List<DvDeploymentModule> dvDeploymentModels = deploymentModuleService.selectDvDeploymentModuleList(search);
			if (dvDeploymentModels == null || dvDeploymentModels.size() == 0) {
				module.setCreateBy("admin");
				module.setStatus(0);
				deploymentModuleService.insertDvDeploymentModule(module);
			} else if (dm.getModuleStatus() == 1) {
				// 有异常更新模块状态
				module.setUpdateBy("admin");
				deploymentModuleService.updateDeploymentModuleByDeviceIdAndModuleCode(module);
			}
		}
		
		
		String em = String.join(" ； ",errorMessages);
		
		// 写入自检表
		DvDeploymentPatrol patrol = new DvDeploymentPatrol();
		patrol.setDeviceId(deviceId);
		patrol.setDeviceCode(deployment.getDeviceCode());
		patrol.setDeviceName(deployment.getDeviceName());
		patrol.setPatrolStatus(0);
		patrol.setStatus(0);
		patrol.setCreateBy("接口");
		patrol.setDeptId(deployment.getDeptId());
		patrol.setCreateUserId(deployment.getCreateUserId());
		patrol.setMessage(em);
		patrol.setPatrolStatus(0);
		
		// 所有自检完成，有异常
		if (errorStatus) {
			patrol.setPatrolStatus(1);

			// ============第四：对异常的模块更新状态
			// 设备状态：1、正常，2、离线，3异常，5关机
			DvDeployment temp = new DvDeployment();
			temp.setDeviceStatus("3");
			temp.setId(deployment.getId());
			deploymentService.updateDvDeployment(temp);
		}
		// ============第五：写入自检表
		patrolService.insertDvDeploymentPatrol(patrol);

		// ============第六：写入自检信息表
		DvSystemInfoDto system = selfInspectionInfo.getSystemInfo();
		if (system != null ) {
			//检测自检信息是否超阀值
			DvDeploymentSystem temp = systemService.selectDeploymentByDeviceId(deviceId);
			
			boolean insertFlag = false;
			if(temp == null) {
				insertFlag = true;
				temp = new DvDeploymentSystem();
			}
			temp.setDeviceId(deviceId);
			temp.setOsVersion(system.getOsVersion());
			temp.setOtherMessage(system.getOtherMessage());
			temp.setMiddlewareVersion(system.getMiddlewareVersion());
			
			MemoryDto memory = system.getMemory();
			if(memory != null) {
				temp.setMemory(memory.getTotal());
				temp.setMemoryRate(memory.getUsageRate());
			}
			
			DiskDto disk = system.getDisk();
			if(disk != null) {
				temp.setDisk(disk.getTotalCapacity());
				temp.setDiskRate(disk.getTotalUsageRate());
			}
			
			CpuDto cpu = system.getCpu();
			if(cpu != null) {
				temp.setCpu(cpu.getProduct());
				temp.setCpuRate(cpu.getUsageRate());
			}
			
			NetworkAdapter networkAdapter = system.getNetworkAdapter();
			if(networkAdapter != null) {
				temp.setIpAddress(networkAdapter.getIp());
				temp.setMac(networkAdapter.getMac());
			}
			
			PrinterDto printer = system.getPrinter();
			if(printer != null) {
				temp.setPaperRate(printer.getPaperRate());
				temp.setCColor(printer.getCcolor());
				temp.setKColor(printer.getKcolor());
				temp.setMColor(printer.getMcolor());
				temp.setYColor(printer.getYcolor());
			}
			
			if (insertFlag) {
				systemService.insertDvDeploymentSystem(temp);
			} else {
				systemService.updateDeploymentSystemByDeviceId(temp);
			}
			
			
			//写入磁盘分区使用信息表
			if(disk != null && disk.getPartitions() != null && disk.getPartitions().size() > 0) {
				List<DiskPartitions> partitions = disk.getPartitions();
				for(DiskPartitions  ps: partitions) {
					DvDeploymentDiskInfo diskInfo = new DvDeploymentDiskInfo();
					diskInfo.setDeviceId(deviceId);		
					diskInfo.setName(ps.getName());
					List<DvDeploymentDiskInfo> diskInfoList = diskInfoService.selectDvDeploymentDiskInfoList(diskInfo);
					//这些条件不能放查询里面，作为条件。
					diskInfo.setCapacity(ps.getCapacity());
					diskInfo.setRate(ps.getUsageRate());
					
					if (diskInfoList != null && diskInfoList.size() > 0) {
						diskInfo.setId(diskInfoList.get(0).getId());
						diskInfoService.updateDvDeploymentDiskInfo(diskInfo);
					}else {
						diskInfoService.insertDvDeploymentDiskInfo(diskInfo);
					}
				}
			}
			
		}//end if (system != null ) 

		// 如果有返回，这里必须R的返回实体或者列表，比如R<DvDeploymentSystem>,或者R<List<DvDeploymentSystem>>
		R r = R.ok();
		return r;
	}

}
